/*
 * Copyright oVirt Authors
 * SPDX-License-Identifier: Apache-2.0
*/

package org.ovirt.engine.api.v3.servers;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import org.ovirt.engine.api.model.Action;
import org.ovirt.engine.api.model.Actionable;
import org.ovirt.engine.api.resource.HostResource;
import org.ovirt.engine.api.restapi.util.ParametersHelper;
import org.ovirt.engine.api.v3.V3Server;
import org.ovirt.engine.api.v3.helpers.V3HostHelper;
import org.ovirt.engine.api.v3.types.V3Action;
import org.ovirt.engine.api.v3.types.V3Host;

@Produces({"application/xml", "application/json"})
public class V3HostServer extends V3Server<HostResource> {
    public V3HostServer(HostResource delegate) {
        super(delegate);
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Actionable
    @Path("activate")
    public Response activate(V3Action action) {
        return adaptAction(getDelegate()::activate, action);
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Actionable
    @Path("approve")
    public Response approve(V3Action action) {
        return adaptAction(getDelegate()::approve, action);
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Actionable
    @Path("commitnetconfig")
    public Response commitNetConfig(V3Action action) {
        return adaptAction(getDelegate()::commitNetConfig, action);
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Actionable
    @Path("deactivate")
    public Response deactivate(V3Action action) {
        return adaptAction(getDelegate()::deactivate, action);
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Actionable
    @Path("enrollcertificate")
    public Response enrollCertificate(V3Action action) {
        return adaptAction(getDelegate()::enrollCertificate, action);
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Actionable
    @Path("fence")
    public Response fence(V3Action action) {
        return adaptAction(getDelegate()::fence, action);
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Actionable
    @Path("forceselectspm")
    public Response forceSelectSpm(V3Action action) {
        return adaptAction(getDelegate()::forceSelectSpm, action);
    }

    @GET
    public V3Host get(@Context HttpHeaders headers, @Context UriInfo ui) {
        // V3 supported a "force" matrix parameter, that is equivalent to calling the "refresh" action:
        boolean force = ParametersHelper.getBooleanParameter(headers, ui, "force", true, false);
        if (force) {
            try {
                getDelegate().refresh(new Action());
            } catch (WebApplicationException exception) {
                throw adaptException(exception);
            }
        }
        V3Host host = adaptGet(getDelegate()::get);

        // In V3 hosts used to have the statistics inline by default:
        V3HostHelper.addStatistics(host);

        return host;
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Actionable
    @Path("install")
    public Response install(V3Action action) {
        return adaptAction(getDelegate()::install, action);
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Actionable
    @Path("iscsidiscover")
    public Response iscsiDiscover(V3Action action) {
        return adaptAction(getDelegate()::iscsiDiscover, action);
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Actionable
    @Path("iscsilogin")
    public Response iscsiLogin(V3Action action) {
        return adaptAction(getDelegate()::iscsiLogin, action);
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Actionable
    @Path("unregisteredstoragedomainsdiscover")
    public Response unregisteredStorageDomainsDiscover(V3Action action) {
        return adaptAction(getDelegate()::unregisteredStorageDomainsDiscover, action);
    }

    @PUT
    @Consumes({"application/xml", "application/json"})
    public V3Host update(V3Host host) {
        return adaptUpdate(getDelegate()::update, host);
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Actionable
    @Path("upgrade")
    public Response upgrade(V3Action action) {
        return adaptAction(getDelegate()::upgrade, action);
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Actionable
    @Path("refresh")
    public Response refresh(V3Action action) {
        return adaptAction(getDelegate()::refresh, action);
    }

    @DELETE
    public Response remove() {
        return adaptRemove(getDelegate()::remove);
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    @Actionable
    @Path("setupnetworks")
    public Response setupNetworks(V3Action action) {
        return adaptAction(getDelegate()::setupNetworks, action);
    }

    @Path("permissions")
    public V3AssignedPermissionsServer getPermissionsResource() {
        return new V3AssignedPermissionsServer(getDelegate().getPermissionsResource());
    }

    @Path("tags")
    public V3AssignedTagsServer getTagsResource() {
        return new V3AssignedTagsServer(getDelegate().getTagsResource());
    }

    @Path("fenceagents")
    public V3FenceAgentsServer getFenceAgentsResource() {
        return new V3FenceAgentsServer(getDelegate().getFenceAgentsResource());
    }

    @Path("devices")
    public V3HostDevicesServer getDevicesResource() {
        return new V3HostDevicesServer(getDelegate().getDevicesResource());
    }

    @Path("hooks")
    public V3HostHooksServer getHooksResource() {
        return new V3HostHooksServer(getDelegate().getHooksResource());
    }

    @Path("nics")
    public V3HostNicsServer getNicsResource() {
        return new V3HostNicsServer(getDelegate().getNicsResource());
    }

    @Path("numanodes")
    public V3HostNumaNodesServer getNumaNodesResource() {
        return new V3HostNumaNodesServer(getDelegate().getNumaNodesResource());
    }

    @Path("storage")
    public V3HostStorageServer getStorageResource() {
        return new V3HostStorageServer(getDelegate().getStorageResource());
    }

    @Path("katelloerrata")
    public V3KatelloErrataServer getKatelloErrataResource() {
        return new V3KatelloErrataServer(getDelegate().getKatelloErrataResource());
    }

    @Path("networkattachments")
    public V3NetworkAttachmentsServer getNetworkAttachmentsResource() {
        return new V3NetworkAttachmentsServer(getDelegate().getNetworkAttachmentsResource());
    }

    @Path("storageconnectionextensions")
    public V3StorageServerConnectionExtensionsServer getStorageConnectionExtensionsResource() {
        return new V3StorageServerConnectionExtensionsServer(getDelegate().getStorageConnectionExtensionsResource());
    }

    @Path("unmanagednetworks")
    public V3UnmanagedNetworksServer getUnmanagedNetworksResource() {
        return new V3UnmanagedNetworksServer(getDelegate().getUnmanagedNetworksResource());
    }

    @Path("statistics")
    public V3StatisticsServer getStatisticsResource() {
        return new V3StatisticsServer(getDelegate().getStatisticsResource());
    }

    @Path("{action: (?:activate|approve|commitnetconfig|deactivate|enrollcertificate|fence|forceselectspm|install|iscsidiscover|iscsilogin|refresh|setupnetworks|unregisteredstoragedomainsdiscover|upgrade)}/{oid}")
    public V3ActionServer getActionResource(@PathParam("action") String action, @PathParam("oid") String oid) {
        return new V3ActionServer(getDelegate().getActionResource(action, oid));
    }
}
